home *** CD-ROM | disk | FTP | other *** search
- CHAPTER 12 COMPATIBILITY WITH OTHER ASSEMBLERS 12-1
-
-
- I gave heavy priority to compatibility when I designed A86; a
- priority just a shade behind the higher priorities of
- reliability, speed, convenience, and power. For those of you who
- feel that "close, but incompatible" is like saying "a little bit
- pregnant", I'm sorry to report that A86 will not assemble all
- Intel/IBM/MSDOS programs, unmodified. But I do think that a vast
- majority of programs can, with a surprisingly little amount of
- massaging, be made to assemble under A86. Furthermore, the
- massaging can be done in such a way as to make the programs still
- acceptable to that old, behemoth assembler.
-
- Version 3.00 of A86 has many compatibility features not present
- on earlier versions. Among the features added since A86 was
- first released are: more general forward references, double-
- quotes for strings, "=" as a synonym for EQU, the RADIX
- directive, and the COMMENT directive. If you tried feeding an
- old source file to a previous A86 and were dismayed by the number
- of error messages you got, try again: things might be more
- manageable now.
-
-
- Conversion of Intel/IBM/MSDOS programs to A86
-
- Following is a list of the things you should watch out for when
- converting from Intel/IBM to A86:
-
- 1. If your program does not fit into 64K, with all the segment
- registers pointing to the same value, then there may be
- instructions in the program for which the old assembler
- generates segment-override prefixes "behind your back". You
- will need to find such references, and generate explicit
- overrides for them. If there are data-tables within the
- program itself, a CS-override is needed. If there are data-
- structures in the stack segment not accessed via a BP-index,
- an SS-override is needed. If ES points to its own segment,
- then an ES-override is needed for accesses (other than STOS
- and MOVS destinations) to that segment.
-
- If you want to remain compatible with the old assembler, then
- you code the overrides by placing the segment register name,
- with a colon, before the memory-access operand in the
- instruction. If you do not need further compatibility, you
- can place the segment register name before the instruction
- mnemonic. For example:
-
- MOV AL,CS:TABLE[SI] ; if you want compatibility do this
- CS MOV AL,TABLE[SI] ; if not you can do it this way
-
- 2. A86 is a bit more restrictive with respect to forward-
- references than IBM's assembler, but not as much as it used to
- be. You'll probably need to resolve just a few ambiguous
- references by appending " B" or " W" to the forward-reference
- name.
- 12-2
- 3. A86 has the feature, not seen in Intel/IBM, that the default
- base for numbers with leading digit 0 is hexadecimal, not
- decimal. This means that you must remove any leading zeroes
- from decimal numbers in your old programs. Note that all
- constants other than those without leading zeroes and without
- trailing base-specifiers are handled identically by A86 and by
- Intel/IBM. The ONLY thing you need to worry about is decimal
- numbers with leading zeroes. Example: the old code line MOV
- AX,00100, meaning decimal 100, should be recoded MOV AX,100,
- without the leading zeroes.
-
- Alternatively, I have added the RADIX command, for
- compatibility with the .RADIX command of IBM's assembler. If
- the program has a .RADIX command at the top of it, then my
- assembler will handle constants identically to the IBM
- assembler; if it does not, you can add a .RADIX 10 to the top
- of the program, for complete compatibility.
-
- For even greater convenience, I have added the +D switch,
- which you can put into your A86 environment variable, to
- achieve decimal functionality without a RADIX 10 command.
-
- 4. A86's macro definition language is different than Intel/IBM's.
- Most macros can be translated by replacing the named
- parameters of the old macros with the dedicated names #n of
- the A86 macro language; and by replacing ENDM with #EM. To
- retain compatibility, you isolate the old macro definitions in
- an INCLUDE file (A86 will ignore the INCLUDE directive), and
- isolate the A86 macro definitions in a separate file, not used
- in an Intel/IBM assembly of the program.
-
- 5. A86 does not support a couple of the more exotic features of
- Intel/IBM assembly language: the RECORD directive and its
- associated operators WIDTH and MASK; and the usage of angle-
- brackets to initialize structure-records. These features
- would have added much complication to the internal structure
- of symbol tables in A86; degrading the speed and the
- reliability of the assembler. I felt that their use was
- sufficiently rare that it was not worth including them for
- compatibility. I would like to hear some feedback on this.
- Does anybody out there use these features heavily? Will they
- be missed in A86?
-
- If your old program does use these features, you will have to
- re-work the areas that use them. Macros can be used to
- duplicate the record and structure initializations. Explicit
- symbol declarations can replace the usage of the WIDTH and
- MASK operators.
-
- 12-3
- Compatibility-symbols recognized by A86
-
- A86 has been programmed to ignore a variety of lines that have
- meaning to Intel/IBM/MSDOS assemblers; but which do nothing for
- A86. These include lines beginning with a period (except .RADIX,
- which is acted upon), percent sign, or dollar sign; and lines
- beginning with ASSUME, INCLUDE, PAGE, SUBTTL, and TITLE. If you
- are porting your program to A86, and you wish to retain the
- option of returning to the other assembler, you may leave those
- lines in your program. If you decide to stay with A86, you can
- remove those lines at your leisure.
-
- In addition, there is a class of symbols now recognized by A86 in
- its .OBJ mode, but still ignored in .COM mode. This includes
- NAME, END, and PUBLIC.
-
- Named SEGMENT and ENDS directives written for other assemblers
- are, of course, recognized by A86's OMF mode. In non-OMF mode,
- A86 treats these as CODE SEGMENT directives. A special exception
- to this is the directive
-
- segname SEGMENT AT atvalue
-
- which is treated by A86 as if it were the following sequence:
-
- segname EQU atvalue
- STRUC
-
- This will accomplish what is usually intended when SEGMENT AT is
- used in a program intended to be a COM file.
-
-
-
- Conversion of A86 Programs to Intel/IBM/MSDOS
-
- I consider this section a bit of a blasphemy, since it's a little
- silly to port programs from a superior assembler, to run on an
- inferior one. However, I myself have been motivated to do so
- upon occasion, when programming for a client not familiar with
- A86; or whose computer doesn't run A86; who therefore wants the
- final version to assemble on Intel's assembler. Since my
- assembler/debugger environment is so vastly superior to any other
- environment, I develop the program using my assembler, and port
- it to the client's environment at the end.
-
- The main key to success in following the above scenarios is to
- exercise supreme will power, and not use any of the wonderful
- language features that exist on A86, but not on the Intel/IBM
- assembler. This is often not easy; and I have devised some
- methods for porting my features to Intel/IBM assemblers:
- 12-4
- 1. I hate giving long sequences of PUSHes and POPs on separate
- lines. If the program is to be ported to a lesser assembler,
- then I put the following lines into a file that only A86 will
- see:
-
- PUSH2 EQU PUSH
- PUSH3 EQU PUSH
- POP2 EQU POP
- POP3 EQU POP
-
- I define macros PUSH2, PUSH3, POP2, POP3 for the lesser
- assembler, that PUSH or POP the appropriate number of
- operands. Then, everywhere in the program where I would
- ordinarily use A86's multiple PUSH/POP feature, I use one or
- more of the PUSHn/POPn mnemonics instead.
-
- 2. I refrain from using the feature of A86 whereby constants with
- a leading zero are default-hexadecimal. All my hex constants
- end with H.
-
- 3. I will usually go ahead and use my local labels L0 through L9;
- then at the last minute convert them to a long sequence of
- labels in sequence: Z100, Z101, Z102, etc. I take care to
- remove all the ">" forward-reference specifiers when I make
- the conversion. The "Z" is used to isolate the local labels
- at the end of the lesser assembler's symbol-table listing.
- This improves the quality of the final program so much that it
- is worth the extra effort needed to convert L0--L9's to Z100-
- Zxxx's.
- 12-5
- 4. I will place declarations B EQU DS:BYTE PTR 0 and W EQU
- DS:WORD PTR 0 at the top of the program. Recall that A86 has
- a "duplicate definition" feature whereby you can EQU an
- already-existing symbol, as long as it is equated to the value
- it already has. This feature extends to the built in symbols
- B and W, so A86 will look at those equates and essentially
- ignore them. On the old assembler, the effect of the
- declarations is to add A86's notation to the old language.
- Example:
-
- B EQU DS:BYTE PTR 0
- W EQU DS:WORD PTR 0
- MOV AX,W[0100] ; replaces MOV AX, DS:WORD PTR 0100
- MOV AL,B[BX] ; replaces MOV AL, DS:BYTE PTR [BX]
-
- Note that I've just given you a tip that means even if you
- don't choose to use A86, you'll never have to use BYTE PTR or
- WORD PTR again! Now don't you just hate BYTE PTR and WORD
- PTR? Isn't the tip alone worth sending me at least $5 for?
-
-